
import requests
import openpyxl
from openpyxl import load_workbook
import time

import json
from urllib.parse import urlparse, parse_qs
    
def extract_huawei_topic_params(url):
    """
    从华为开发者社区URL中提取topic_id和fid参数
    :param url: 帖子URL
    :return: 元组(topic_id, fid)或(None, None)如果提取失败
    """
    try:
        parsed_url = urlparse(url)
        path_parts = parsed_url.path.split('/')
        topic_id = path_parts[-1] if path_parts else None
        fid = parse_qs(parsed_url.query).get('fid', [None])[0]
        return topic_id, fid
    except Exception:
        return None, None

def get_huawei_topic_field(url, target_field="views"):
    """
    获取华为开发者社区论坛帖子的阅读量
    :param url: 帖子URL，例如 "https://developer.huawei.com/consumer/cn/forum/topic/0203168518087929617?fid=0101592429757310384"
    :return: 阅读量数字或错误信息
    """
    try:
        # 从URL中提取参数
        topic_id, fid = extract_huawei_topic_params(url)
        if not topic_id or not fid:
            return "URL格式不正确，无法提取topic_id和fid"
            
        # 华为开发者社区API接口
        api_url = "https://svc-drcn.developer.huawei.com/community/servlet/consumer/partnerforumservice/v1/open/getTopicDetail"
        
        # 请求头
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36",
            "Content-Type": "application/json;charset=UTF-8",
            "Origin": "https://developer.huawei.com",
            "Referer": "https://developer.huawei.com/",
        }
        
        # 请求体参数
        payload = {
            "topicId": topic_id,
            "fid": fid
        }
        
        # 发送POST请求
        response = requests.post(api_url, headers=headers, data=json.dumps(payload))
        response.raise_for_status()  # 检查请求是否成功
        
        # 解析JSON响应
        data = response.json()
        
        # 检查API返回状态码
        if data.get("code") == 0:
            views = data.get("result", {}).get(target_field)
            if views is not None:
                return str(views)
            else:
                return f"响应中未找到 {target_field} 字段"
        else:
            return f"API返回错误: {data.get('message', '未知错误')}"
            
    except requests.exceptions.RequestException as e:
        return f"请求失败: {str(e)}"
    except json.JSONDecodeError:
        return "响应解析失败"
    except Exception as e:
        return f"发生错误: {str(e)}"


def get_huawei_blog_field(url, target_field="views"):
    """
    获取华为开发者社区博客页面的指定字段数据
    :param url: 博客URL，例如 "https://developer.huawei.com/consumer/cn/blog/topic/03172320109401009"
    :param target_field: 要提取的字段名，默认为"views"（阅读量）
    :return: 字段值或错误信息
    """
    try:
        # 从URL中提取博客ID
        blog_id = url.split("/")[-1]
        if not blog_id or not blog_id.startswith("0"):
            return "URL格式不正确，无法提取博客ID"
            
        # 新的API接口
        api_url = "https://svc-drcn.developer.huawei.com/community/servlet/consumer/partnerblogservice/v1/openblog/getBlogInfoById"
        
        # 请求头
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36",
            "Content-Type": "application/json;charset=UTF-8",
            "Origin": "https://developer.huawei.com",
            "Referer": url
        }
        
        # 请求体参数
        payload = {
            "blogId": blog_id
        }
        
        # 发送POST请求
        response = requests.post(api_url, headers=headers, json=payload)
        response.raise_for_status()
        
        # 解析响应
        data = response.json()
        
        # 检查API返回状态
        if data.get("code") == 0:
            result = data.get("result", {})
            field_value = result.get(target_field)
            if field_value is not None:
                return str(field_value)  # 确保返回字符串
            else:
                return f"响应中未找到 {target_field} 字段"
        else:
            return f"API返回错误: {data.get('message', '未知错误')}"
            
    except requests.exceptions.RequestException as e:
        return f"请求失败: {str(e)}"
    except json.JSONDecodeError:
        return "响应解析失败"
    except Exception as e:
        return f"发生错误: {str(e)}"

def process_excel_file(
    file_path: str,
    sheet_name: str = None,  # 默认当前活动页签
    url_column: str = "T",   # URL所在列
    result_column: str = "U" # 结果写入列
) -> None:
    """
    从Excel文件的指定页签和列中读取URL，根据URL类型自动选择提取方法，
    统计阅读数并保存结果。

    Args:
        file_path (str): 输入Excel文件路径
        sheet_name (str, optional): 页签名称。默认为当前活动页签
        url_column (str, optional): URL列名（如 "D"）。默认为 "D"
        result_column (str, optional): 结果写入列名（如 "E"）。默认为 "E"
    """
    # 加载Excel文件
    wb = load_workbook(file_path)
    ws = wb[sheet_name] if sheet_name else wb.active

    # 将列名转换为列索引
    url_col_idx = openpyxl.utils.column_index_from_string(url_column)
    result_col_idx = openpyxl.utils.column_index_from_string(result_column)

    # 获取URL列的所有行
    for row_idx, row in enumerate(ws.iter_rows(min_col=url_col_idx, max_col=url_col_idx, values_only=True), start=1):
        url = row[0]
        if not isinstance(url, str) or not url.strip().startswith("http"):
            continue

        print(f"处理URL[{row_idx}]: {url}")
        
        try:
            # 根据URL类型选择对应的提取方法
            if "/forum/topic/" in url:
                views = get_huawei_topic_field(url)
            elif "/blog/topic/" in url:
                views = get_huawei_blog_field(url)
            else:
                print(f"不支持的URL类型: {url}")
                continue

            print(f"阅读量: {views}")
            ws.cell(row=row_idx, column=result_col_idx, value=views)
            time.sleep(1)  # 请求间隔
            print(f"已更新行 {row_idx} 的数据 URL: {url}, Views: {views}")
            
        except Exception as e:
            print(f"处理失败: {str(e)}")
            ws.cell(row=row_idx, column=result_col_idx, value=f"Error: {str(e)}")

    # 保存结果
    wb.save(file_path)
    print(f"处理完成，结果已保存到: {file_path}")
    
# 示例使用
if __name__ == "__main__":
    process_excel_file(
        file_path="C:/Users/qwx1425249/Desktop/data/开发者空间案例内外媒运营数据看板.xlsx",
        sheet_name="案例发布计划",  # 指定页签名称（可选）
        url_column="T",
        result_column="U"
    )
